package com.config;


import com.yc.grpc.GrpcHostProperties;
import com.yc.grpc.RpcClient;
import com.yc.grpc.RpcFactoryBean;
import com.yc.grpc.RpcScannerConfigurer;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @Author: ZhouJianLong
 * @Date: 2024/07/19/17:25
 * @Description:
 */
@Configuration
@EnableConfigurationProperties(GrpcHostProperties.class)
public class RpcConfiguration {

    @Import(AutoConfiguredRpcScannerRegistrar.class)
    @Configuration
    @ConditionalOnMissingBean({RpcScannerConfigurer.class, RpcFactoryBean.class})
    public static class AutoConfiguredRpcScannerRegistrarConfig{

    }
    public static class AutoConfiguredRpcScannerRegistrar implements BeanFactoryAware, EnvironmentAware,ImportBeanDefinitionRegistrar {

        private BeanFactory beanFactory;
        private Environment environment;
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

            List<String> packages = AutoConfigurationPackages.get(this.beanFactory);
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RpcScannerConfigurer.class);
            builder.addPropertyValue("basePackage",StringUtils.collectionToCommaDelimitedString(packages));
            builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            builder.addPropertyValue("annotationClass", RpcClient.class);
            registry.registerBeanDefinition(generateBaseBeanName(importingClassMetadata,0),builder.getBeanDefinition());

        }
        private static String generateBaseBeanName(AnnotationMetadata importingClassMetadata, int index) {
            return importingClassMetadata.getClassName() + "#" + RpcScannerConfigurer.class.getSimpleName() + "#" + index;
        }

        @Override
        public void setBeanFactory(BeanFactory beanFactory) {
            this.beanFactory = beanFactory;
        }

        @Override
        public void setEnvironment(Environment environment) {
            this.environment = environment;
        }
    }




}
